#ifndef _FOREST_HPP_
#define _FOREST_HPP_

#include <list>
#include <map>
#include <vector>

#include "Organism.hpp"

/**
 * Class Forest is the umbrella class
 *
 * All organisms and plants are members of the forest.
 *
 */
class Forest
{
public:

  /**
   * Puts an organism on the kill list.
   *
   * @param str  is the name of the organism
   */
  void kill(const std::string& str) {
    killVec.push_back(str);
  }

  /**
   * Kills all of the organisms on the kill list
   */
  void kill();

  /**
   * a list of the organisms that make up this little biosphere.
   */
  std::list<Organism*> ecosystem;

  /**
   * When an organism is born, the forest
   * takes note, adding it to its list of
   * organisms in the ecosystem and incrementing
   * the population.
   *
   * @param org the organism that was just born
   */
  void addOrganism(const Organism& org) {
    Organism *p = org.clone();
    ecosystem.push_back(p);
    population[org.getName()]++;
  }

  /**
   * When an organism is eaten or too old, 
   * the forest also takes note,
   * removing the organism from its list
   * of organisms in the ecosystem and decrementing the 
   * population.
   */
  void removeOrganism(std::list<Organism*>::iterator &iter) {
    delete *iter;
    population[(*iter)->getName()]--;
    iter = ecosystem.erase(iter);
  }

  /**
   * Returns the current population of a certain
   * type of organism.
   *
   * @param name is the name of the organism type.
   * @return population of that organism type.
   */
  int getPopulation(const std::string& name) const {
    return population.find(name)->second;
  }

  /**
   * Returns the current population of a certain
   * type of organism.
   *
   * @return population of that organism type.
   */
  int getPopulation() const { 
    return ecosystem.size(); 
  }

private:

  /**
   * a map of each type of organism and the number 
   * of members of that type of organism.
   */
  std::map<std::string, int> population;

  /**
   * List of organisms that have been eaten:
   */
  std::vector<std::string> killVec;
};

#endif
